package idomains

import (
	"gitee.com/djaf/my-certs/app/classes/domains"
	"gitee.com/djaf/my-certs/app/data/dxo"
	"gitee.com/djaf/my-certs/app/data/entity"
	"github.com/starter-go/security/random"
	"gorm.io/gorm"
)

// DomainDaoImpl ...
type DomainDaoImpl struct {

	//starter:component

	_as func(domains.DAO) //starter:as("#")

	Agent       dxo.DatabaseAgent  //starter:inject("#")
	UUIDService random.UUIDService //starter:inject("#")

}

func (inst *DomainDaoImpl) _impl() domains.DAO {
	return inst
}

func (inst *DomainDaoImpl) model() *entity.Domain {
	return new(entity.Domain)
}

func (inst *DomainDaoImpl) modelList() []*entity.Domain {
	return make([]*entity.Domain, 0)
}

func (inst *DomainDaoImpl) makeResult(item *entity.Domain, res *gorm.DB) (*entity.Domain, error) {
	err := res.Error
	if err != nil {
		return nil, err
	}
	return item, nil
}

// Find ...
func (inst *DomainDaoImpl) Find(db *gorm.DB, id dxo.DomainID) (*entity.Domain, error) {
	m := inst.model()
	db = inst.Agent.DB(db)
	res := db.First(m, id)
	return inst.makeResult(m, res)
}

// List ...
func (inst *DomainDaoImpl) List(db *gorm.DB) ([]*entity.Domain, error) {
	list := inst.modelList()
	db = inst.Agent.DB(db)
	res := db.Find(&list)
	if res.Error != nil {
		return nil, res.Error
	}
	return list, nil
}

// Insert ...
func (inst *DomainDaoImpl) Insert(db *gorm.DB, item *entity.Domain) (*entity.Domain, error) {

	uuid := inst.UUIDService.Build().Class("entity.Domain").Generate()

	item.ID = 0
	item.UUID = uuid

	db = inst.Agent.DB(db)
	res := db.Create(item)
	return inst.makeResult(item, res)
}

// Update ...
func (inst *DomainDaoImpl) Update(db *gorm.DB, id dxo.DomainID, fn func(item *entity.Domain)) (*entity.Domain, error) {
	ent := inst.model()
	db = inst.Agent.DB(db)
	res := db.First(ent, id)
	if res.Error != nil {
		return nil, res.Error
	}
	fn(ent)
	res = db.Save(ent)
	return inst.makeResult(ent, res)
}

// Remove ...
func (inst *DomainDaoImpl) Remove(db *gorm.DB, id dxo.DomainID) error {
	m := inst.model()
	db = inst.Agent.DB(db)
	res := db.Delete(m, id)
	return res.Error
}

// FindByName ...
func (inst *DomainDaoImpl) FindByName(db *gorm.DB, name dxo.DomainName) (*entity.Domain, error) {
	item := inst.model()
	db = inst.Agent.DB(db)
	res := db.Where("name=?", name).First(item)
	return inst.makeResult(item, res)
}
